import { useEffect, useRef, useState } from "react"

function App() { 
  /* 
  1.自动推导:
  通常React会根据传入useState的默认值来自动推导类型,不需要显式标注类型
  value: 类型为boolean
  setValue: 参数类型为boolean

  2. 传递泛型函数
  useState本身是一个泛型函数，可以传入具体的自定义类型
  当不知道状态的初始值是什么，将useState的初始值为null是一个常见的做法，可以通过具体类型联合null来做显式注解
  限制useState函数参数的初始值可以是 User | null
  限制setUser函数的参数类型可以是 User

  */

  type User = {
    name:string,
    age:number
  }

  const [value , setValue] = useState(false)
  const [user, setUser] = useState<User | null>(null)

  // 3. 为事件回调添加类型约束需要使用React内置的泛型函数来做，比如最常见的鼠标点击事件和表单输入事件
  // 说明：通过泛型函数约束了整个事件回调函数的类型，主要是为了约束事件参数e的类型
  const click: React.MouseEventHandler<HTMLButtonElement> = () => {
    setUser({
      name:'ts',
      age:18
    })
  }
  const changeInp: React.ChangeEventHandler<HTMLInputElement> = (e) => {
    console.log(e.target.value);
  }


  // 4. 使用useRef获取dom元素  指定元素类型
  const inpRef = useRef<HTMLInputElement>(null)

  // 实现初始化聚焦
  useEffect(()=>{
    inpRef.current?.focus()
  },[])


  return (
    <div>
      查看值: {value? '显示':'隐藏' }
      <button onClick={()=>setValue(!value)}>changeValue</button>
      <div>
        查看用户{user?.name}
        <button onClick={click}>setUser</button>
      </div>
      <input type="text" ref={inpRef} onChange={changeInp} />

    </div>
  )
}

export default App
